/**
 * 项目创建模块
 * 
 * 负责协调整个Flutter项目的创建流程，包括用户交互、项目初始化、模板复制和环境配置
 * 支持通过命令行参数或交互式方式创建不同类型和模板的Flutter项目
 */

import { execSync } from 'child_process';
import ora from 'ora';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import fsExtra from 'fs-extra';
const { existsSync, mkdirSync, accessSync, constants, removeSync } = fsExtra;
import { getUserInteraction } from './userInteraction.js';
import { copyLibDirectory, copyVscode } from './libCopier.js';
import { runFlutterCreate } from './flutterProjectCreator.js';
import { printColored, updateReadme, openProjectInIde, getTemplateBranch } from './utils.js';

/**
 * 生成默认项目名称
 * 
 * 根据项目类型和当前日期生成唯一的默认项目名称，避免命名冲突
 * 应用类型项目以'flutter_app_'为前缀，模块类型以'flutter_module_'为前缀
 * 
 * @param {string} projectType - 项目类型 ('app' 或 'module')
 * @returns {string} 带时间戳的默认项目名称
 */
function getDefaultProjectName (projectType) {
  const date = new Date();
  const timestamp = `${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}${String(date.getDate()).padStart(2, '0')}`;
  return projectType === 'app' ? `flutter_app_${timestamp}` : `flutter_module_${timestamp}`;
}

/**
 * 创建项目的主函数
 * 
 * 协调整个项目创建流程，包括获取用户输入、验证环境、创建Flutter项目、复制模板文件、
 * 生成README和自动打开IDE等步骤。支持命令行参数和交互式两种模式
 * 
 * @param {Object} [options={}] - 命令行参数选项
 * @param {boolean} [options.useCommandLineArgs=false] - 是否使用命令行参数
 * @param {string} [options.projectType] - 项目类型 ('app','module','package','plugin')
 * @param {string} [options.templateType] - 模板类型 ('only', 'min', 'normal', 'pro')
 * @param {string} [options.stateManager] - 状态管理 ('state', 'GetX', 'Provider', etc.)
 * @param {string} [options.projectName] - 项目名称
 * @param {string} [options.packageName] - 包名
 * @param {string} [options.parentDir] - 项目存放路径
 * @param {string} [options.ideChoice] - IDE选择 ('vscode', 'android_studio', etc.)
 * @param {string} [options.flutterSdk] - Flutter SDK路径
 * @example
 * // 交互式创建项目
 * createProject();
 * // 命令行模式创建项目
 * createProject({
 *   useCommandLineArgs: true,
 *   projectType: 'app',
 *   templateType: 'pro',
 *   projectName: 'my_app',
 *   packageName: 'com.example.myapp',
 *   parentDir: '/path/to/projects'
 * });
 */
async function createProject (options = {}) {
  try {
    // 获取项目类型 - 从命令行参数或交互式输入
    const projectType = options.useCommandLineArgs ? options.projectType : await getUserInteraction.getProjectType();
    let templateType = '';
    // 项目类型为app或module时，获取模板类型
    if (projectType == "app" || projectType == "module") {
      // 获取模板类型 - 从命令行参数或交互式输入
      templateType = options.useCommandLineArgs ? options.templateType : await getUserInteraction.getTemplateType();
    } else {
      // 项目类型为package或plugin时，模板类型固定为only
      templateType = 'only';
    }


    // 获取状态管理 - 仅在非基础模板时需要
    let stateManager = '';
    if (templateType != 'only' && templateType != 'min') {
      stateManager = options.useCommandLineArgs ? options.stateManager : await getUserInteraction.getStateManager();
    }

    // 获取当前脚本所在目录作为源目录
    const sourceDir = dirname(fileURLToPath(import.meta.url));

    // 获取项目信息 - 从命令行参数或交互式输入
    let projectName, packageName, parentDir, targetDir, flutterSdkPath;

    if (options.useCommandLineArgs && options.projectName && options.packageName && options.parentDir && options.flutterSdk) {
      // 使用命令行参数
      projectName = options.projectName;
      packageName = options.packageName;
      parentDir = options.parentDir;
      targetDir = join(parentDir, projectName);
      flutterSdkPath = options.flutterSdk;
    } else if (options.useCommandLineArgs) {
      // 命令行参数不完整，使用交互式输入，但预填充已提供的参数
      const defaultName = getDefaultProjectName(projectType);
      const projectInfo = await getUserInteraction.getProjectInfo(
        projectType,
        options.projectName || defaultName,
        options.packageName || `com.example.${options.projectName || defaultName}`,
        options.parentDir
      );
      projectName = projectInfo.projectName;
      packageName = projectInfo.packageName;
      parentDir = projectInfo.parentDir;
      targetDir = projectInfo.targetDir;
      flutterSdkPath = projectInfo.flutterSdkPath;
    } else {
      // 完全使用交互式输入
      const projectInfo = await getUserInteraction.getProjectInfo(projectType);
      // 项目名字
      projectName = projectInfo.projectName;
      // 包名 
      packageName = projectInfo.packageName;
      // 项目存放地址
      parentDir = projectInfo.parentDir;
      targetDir = projectInfo.targetDir;
      flutterSdkPath = projectInfo.flutterSdkPath;
    }

    console.log('flutterSdkPath:', flutterSdkPath);
    // 验证目标目录是否存在并具有写权限
    if (!existsSync(parentDir)) {
      try {
        mkdirSync(parentDir, { recursive: true });
      } catch (e) {
        printColored(`错误: 无法创建目录 ${parentDir}: ${e.message}`, 'red');
        return;
      }
    }

    // 检查目标目录是否具有写权限
    try {
      accessSync(parentDir, constants.W_OK);
    } catch (e) {
      printColored(`错误: 目录 ${parentDir} 没有写权限`, 'red');
      return;
    }

    // 检查目标目录是否已存在
    if (existsSync(targetDir)) {
      const overwrite = await getUserInteraction.confirmOverwrite(targetDir);
      if (!overwrite) {
        printColored("操作已取消", 'yellow');
        return;
      }

      // 删除已存在的目录
      removeSync(targetDir);
    }

    // 使用flutter create创建新项目
    const flutterCreateSpinner = ora('正在创建Flutter项目...').start();
    const flutterCreateResult = await runFlutterCreate(targetDir, projectName, packageName, projectType, flutterSdkPath);
    if (!flutterCreateResult) {
      flutterCreateSpinner.fail('Flutter项目创建失败');
      return;
    }
    flutterCreateSpinner.succeed('Flutter项目创建成功');



    if (templateType != 'only') {
      // 获取模板分支名称
      const templateBranch = getTemplateBranch(templateType, stateManager);
      // 复制项目文件
      const copySpinner = ora('正在复制项目模板...').start();
      const copyResult = await copyLibDirectory(sourceDir, targetDir, projectName, projectType, templateType, packageName, templateBranch);
      if (!copyResult) {
        copySpinner.fail('项目模板复制失败');
        return;
      }
      copySpinner.succeed('项目模板复制成功');
      // 更新README.md
      updateReadme(targetDir, projectName, packageName);
    }




    // 打印完成信息
    printColored("\n新项目已创建成功！", 'green');
    printColored(`项目路径: ${targetDir}`, 'green');
    printColored("\n执行以下命令开始开发:\n", 'blue');
    printColored(`cd ${targetDir}`, 'yellow');
    printColored(`flutter pub get`, 'yellow');
    printColored(`flutter run`, 'yellow');

    // 获取用户选择的IDE类型 - 从命令行参数或交互式输入
    const ideChoice = options.useCommandLineArgs ? options.ideChoice : await getUserInteraction.getIdeChoice();
    if (ideChoice == 'vscode' && templateType != 'only') {
      await copyVscode(targetDir);
    }
    if ((ideChoice == 'vscode' || ideChoice == 'android_studio') && flutterSdkPath === 'flutter') {
      const pubGetSpinner = ora('正在获取Flutter依赖...').start();
      try {
        // 执行flutter pub get命令
        execSync(`cd ${targetDir} && flutter pub get`, { stdio: 'inherit' });
        pubGetSpinner.succeed('依赖获取成功');
      } catch (e) {
        pubGetSpinner.fail('依赖获取失败');
        printColored(`错误信息: ${e.message}`, 'red');
      }
    }
    // 自动打开项目
    openProjectInIde(targetDir, ideChoice);

  } catch (error) {
    if (error.isTtyError) {
      printColored("\n当前环境不支持交互式提示", 'red');
    } else {
      printColored(`\n错误: ${error.message}`, 'red');
    }
  }
}

export { createProject };